"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 硬件故障类--网卡
Case Name   : TPCC过程备机网卡中断3分钟
Create At   : 2020-10-28
Owner       : n@ningyali
Description :
    1、执行tpcc过程停止DN备网卡3分钟
    2、恢复后查询集群状态
    3、主备数据一致性检查
Expect      :
    1、执行tpcc过程停止DN备网卡3分钟，注入故障成功，tpcc执行正常
    2、恢复后查询集群状态正常
    3、主备数据一致性检查通过
History     :
    modified：2021-9-3 by 5328113;cfe注入故障返回结果变更，优化查询网卡及断言；
    created： 2020/10/28  created by n@ningyali
"""

import unittest
from yat.test import Node
from yat.test import macro

from testcase.utils.CommonSH import *
from testcase.utils.Common import *
from testcase.utils.ComThread import *


class StandbyNodeNetDown(unittest.TestCase):
    primary_sh = CommonSH('PrimaryDbUser')
    standby1_sh = CommonSH('Standby1DbUser')
    standby2_sh = CommonSH('Standby2DbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('-----------Opengauss_Reliability_Hardware_Case008:开始执行------------')
        self.primary_root_node = Node(node='PrimaryRoot')
        self.primary_user_node = Node(node='PrimaryDbUser')
        self.standby1_root_node = Node(node='Standby1Root')
        self.standby1_user_node = Node(node='Standby1DbUser')
        self.standby2_user_node = Node(node='Standby2DbUser')
        self.com = Common()
        self.Constant = Constant()

    def test_main(self):
        self.log.info("---------------启线程执行tpcc----------------")
        tpcc_thread = ComThread(self.com.startTPCC, args=(self.primary_root_node, macro.TPCC_PATH))
        tpcc_thread.setDaemon(True)
        tpcc_thread.start()

        self.log.info("-------------获取网卡---------------")
        shell_cmd = "ifconfig"
        self.log.info(shell_cmd)
        msg = self.standby1_root_node.sh(shell_cmd).result()
        network_card_list = msg.split('\n\n')
        self.log.info(network_card_list)
        network_card = ''
        for network_card_item in network_card_list:
            if self.standby1_root_node.db_host in network_card_item:
                network_card = network_card_item.split(':')[0].strip()
                self.log.info(network_card)

        self.log.info("-------------停止DN主网卡3分钟---------------")
        inject_command = f"rNet_down (dev, time)values({network_card}, 180)"
        msg = self.com.cfe_inject(self.standby1_root_node, inject_command)
        self.log.info(msg)
        self.assertIn(self.Constant.cfe_inject_netdown_success_msg, msg)

        self.log.info("---------------故障过程中，业务无报错----------------")
        tpcc_thread.join(int(macro.TPCC_RUN_MAX_TIME) * 2)
        tpcc_result = tpcc_thread.get_result()
        self.log.info(tpcc_result)
        self.assertIn(self.Constant.TPCC_SUCCESS_MSG, tpcc_result)

        time.sleep(180)

        self.log.info("-------------故障消除后，数据库状态恢复正常---------------")
        db_status = self.primary_sh.getDbClusterStatus('detail')
        self.log.info(db_status)

        self.log.info("-------------校验刷脏页是否完成---------------")
        dirty_page_finshed_flag = self.primary_sh.check_whether_remain_dirty_page()
        self.assertTrue(dirty_page_finshed_flag)

        self.log.info("-------------校验备机是否完成数据同步---------------")
        flag_1 = self.standby1_sh.check_data_consistency()
        self.assertTrue(flag_1)
        flag_2 = self.standby2_sh.check_data_consistency()
        self.assertTrue(flag_2)

        self.log.info("-------------校验主备数据一致---------------")
        nodes_tuple = (self.primary_user_node, self.standby1_user_node, self.standby2_user_node)
        flag = self.com.check_data_sample_by_all(r'\d', *nodes_tuple)
        self.assertTrue(flag)

        table_dict = self.com.format_sql_result(self.primary_sh.executDbSql(r'\d'))
        table_name = table_dict.get('Name')
        for name in table_name:
            select_sql = f'select count(*) from {name};'
            flag = self.com.check_data_sample_by_all(select_sql, *nodes_tuple)
            self.assertTrue(flag)

    def tearDown(self):
        self.log.info('--------Opengauss_Reliability_Hardware_Case008:执行完成-----------')
